// animationSystem.js - 动画系统和后处理效果
import { reactive, ref, computed } from 'vue'

/**
 * 动画系统 - 管理关键帧动画、骨骼动画、形变动画
 */
export class AnimationSystem {
    constructor() {
        this.animations = new Map()
        this.activeAnimations = new Map()
        this.mixer = new AnimationMixer()
        this.clock = {
            elapsedTime: 0,
            deltaTime: 0,
            lastTime: performance.now()
        }
    }

    /**
     * 创建关键帧动画
     */
    createKeyframeAnimation(name, config) {
        const animation = new KeyframeAnimation(name, config)
        this.animations.set(name, animation)
        return animation
    }

    /**
     * 创建骨骼动画
     */
    createSkeletalAnimation(name, skeleton, tracks) {
        const animation = new SkeletalAnimation(name, skeleton, tracks)
        this.animations.set(name, animation)
        return animation
    }

    /**
     * 创建形变动画（Morph Target）
     */
    createMorphAnimation(name, targets, weights) {
        const animation = new MorphAnimation(name, targets, weights)
        this.animations.set(name, animation)
        return animation
    }

    /**
     * 播放动画
     */
    play(name, options = {}) {
        const animation = this.animations.get(name)
        if (!animation) {
            console.warn(`动画不存在: ${name}`)
            return null
        }

        const clip = this.mixer.clipAction(animation, options)
        clip.play()

        this.activeAnimations.set(name, clip)
        return clip
    }

    /**
     * 停止动画
     */
    stop(name) {
        const clip = this.activeAnimations.get(name)
        if (clip) {
            clip.stop()
            this.activeAnimations.delete(name)
        }
    }

    /**
     * 暂停动画
     */
    pause(name) {
        const clip = this.activeAnimations.get(name)
        if (clip) {
            clip.pause()
        }
    }

    /**
     * 更新动画系统
     */
    update() {
        const currentTime = performance.now()
        this.clock.deltaTime = (currentTime - this.clock.lastTime) / 1000
        this.clock.elapsedTime += this.clock.deltaTime
        this.clock.lastTime = currentTime

        // 更新动画混合器
        this.mixer.update(this.clock.deltaTime)

        // 更新活跃的动画
        this.activeAnimations.forEach((clip, name) => {
            if (clip.finished) {
                this.activeAnimations.delete(name)
            }
        })
    }

    /**
     * 获取动画信息
     */
    getAnimationInfo() {
        return {
            totalAnimations: this.animations.size,
            activeAnimations: this.activeAnimations.size,
            elapsedTime: this.clock.elapsedTime
        }
    }

    /**
     * 清理资源
     */
    dispose() {
        this.activeAnimations.clear()
        this.animations.clear()
        this.mixer.dispose()
    }
}

/**
 * 动画混合器
 */
class AnimationMixer {
    constructor() {
        this.clips = []
        this.time = 0
    }

    /**
     * 创建动画剪辑动作
     */
    clipAction(animation, options = {}) {
        const clip = new AnimationClip(animation, {
            loop: options.loop !== false,
            weight: options.weight || 1.0,
            timeScale: options.timeScale || 1.0,
            fadeDuration: options.fadeDuration || 0.0,
            ...options
        })

        this.clips.push(clip)
        return clip
    }

    /**
     * 更新混合器
     */
    update(deltaTime) {
        this.time += deltaTime

        // 更新所有剪辑
        this.clips = this.clips.filter(clip => {
            if (clip.isPlaying) {
                clip.update(deltaTime)
                return !clip.finished
            }
            return true
        })
    }

    /**
     * 清理资源
     */
    dispose() {
        this.clips.forEach(clip => clip.dispose())
        this.clips = []
    }
}

/**
 * 动画剪辑
 */
class AnimationClip {
    constructor(animation, options) {
        this.animation = animation
        this.options = options

        this.isPlaying = false
        this.isPaused = false
        this.finished = false

        this.time = 0
        this.weight = options.weight
        this.timeScale = options.timeScale
        this.fadeWeight = 0
        this.fadeDuration = options.fadeDuration
        this.fadeDirection = 0 // 1: fade in, -1: fade out
    }

    /**
     * 播放
     */
    play() {
        this.isPlaying = true
        this.isPaused = false
        this.finished = false
        this.fadeDirection = 1
    }

    /**
     * 停止
     */
    stop() {
        this.isPlaying = false
        this.isPaused = false
        this.time = 0
        this.fadeWeight = 0
    }

    /**
     * 暂停
     */
    pause() {
        this.isPaused = true
    }

    /**
     * 淡出
     */
    fadeOut(duration = 1.0) {
        this.fadeDuration = duration
        this.fadeDirection = -1
    }

    /**
     * 更新剪辑
     */
    update(deltaTime) {
        if (!this.isPlaying || this.isPaused) return

        // 更新时间
        this.time += deltaTime * this.timeScale

        // 处理淡入淡出
        if (this.fadeDuration > 0) {
            this.fadeWeight = Math.max(0, Math.min(1,
                this.fadeWeight + (this.fadeDirection * deltaTime / this.fadeDuration)
            ))

            if (this.fadeDirection === -1 && this.fadeWeight <= 0) {
                this.finished = true
                return
            }
        } else {
            this.fadeWeight = 1
        }

        // 检查循环
        if (this.time >= this.animation.duration) {
            if (this.options.loop) {
                this.time = this.time % this.animation.duration
            } else {
                this.time = this.animation.duration
                this.finished = true
            }
        }

        // 应用动画
        this.animation.apply(this.time, this.weight * this.fadeWeight)
    }

    /**
     * 清理资源
     */
    dispose() {
        this.animation = null
    }
}

/**
 * 关键帧动画
 */
class KeyframeAnimation {
    constructor(name, config) {
        this.name = name
        this.duration = config.duration || 1.0
        this.tracks = config.tracks || []
        this.target = config.target
    }

    /**
     * 添加轨道
     */
    addTrack(property, keyframes, interpolation = 'linear') {
        this.tracks.push({
            property,
            keyframes,
            interpolation
        })
    }

    /**
     * 应用动画
     */
    apply(time, weight = 1.0) {
        if (!this.target) return

        this.tracks.forEach(track => {
            const value = this.interpolateTrack(track, time)
            if (value !== null) {
                // 混合权重
                if (weight < 1.0 && this.target[track.property] !== undefined) {
                    const currentValue = this.target[track.property]
                    this.target[track.property] = this.mixValues(currentValue, value, weight)
                } else {
                    this.target[track.property] = value
                }
            }
        })
    }

    /**
     * 轨道插值
     */
    interpolateTrack(track, time) {
        const keyframes = track.keyframes
        if (keyframes.length === 0) return null

        // 找到当前时间段的关键帧
        let prevFrame = null
        let nextFrame = null

        for (let i = 0; i < keyframes.length; i++) {
            if (keyframes[i].time <= time) {
                prevFrame = keyframes[i]
            } else {
                nextFrame = keyframes[i]
                break
            }
        }

        if (!prevFrame) return keyframes[0].value
        if (!nextFrame) return prevFrame.value

        // 计算插值因子
        const t = (time - prevFrame.time) / (nextFrame.time - prevFrame.time)

        // 根据插值类型进行插值
        switch (track.interpolation) {
            case 'step':
                return prevFrame.value
            case 'linear':
                return this.linearInterpolate(prevFrame.value, nextFrame.value, t)
            case 'cubic':
                return this.cubicInterpolate(prevFrame, nextFrame, t)
            default:
                return this.linearInterpolate(prevFrame.value, nextFrame.value, t)
        }
    }

    /**
     * 线性插值
     */
    linearInterpolate(a, b, t) {
        if (typeof a === 'number') {
            return a + (b - a) * t
        } else if (Array.isArray(a)) {
            return a.map((val, i) => val + (b[i] - val) * t)
        }
        return a
    }

    /**
     * 三次插值
     */
    cubicInterpolate(prevFrame, nextFrame, t) {
        // 简化版本，实际实现需要考虑切线
        return this.linearInterpolate(prevFrame.value, nextFrame.value,
            t * t * (3 - 2 * t) // smoothstep
        )
    }

    /**
     * 混合值
     */
    mixValues(a, b, weight) {
        return this.linearInterpolate(a, b, weight)
    }
}

/**
 * 骨骼动画
 */
class SkeletalAnimation {
    constructor(name, skeleton, tracks) {
        this.name = name
        this.skeleton = skeleton
        this.tracks = tracks
        this.duration = this.calculateDuration()
    }

    /**
     * 计算动画时长
     */
    calculateDuration() {
        let maxDuration = 0
        this.tracks.forEach(track => {
            if (track.keyframes.length > 0) {
                const lastKeyframe = track.keyframes[track.keyframes.length - 1]
                maxDuration = Math.max(maxDuration, lastKeyframe.time)
            }
        })
        return maxDuration
    }

    /**
     * 应用骨骼动画
     */
    apply(time, weight = 1.0) {
        this.tracks.forEach(track => {
            const bone = this.skeleton.getBone(track.boneName)
            if (bone) {
                const transform = this.interpolateTransform(track, time)
                if (transform) {
                    // 应用变换到骨骼
                    bone.applyTransform(transform, weight)
                }
            }
        })

        // 更新骨骼矩阵
        this.skeleton.update()
    }

    /**
     * 插值变换
     */
    interpolateTransform(track, time) {
        return {
            position: this.interpolateProperty(track.position, time),
            rotation: this.interpolateProperty(track.rotation, time),
            scale: this.interpolateProperty(track.scale, time)
        }
    }

    /**
     * 插值属性
     */
    interpolateProperty(keyframes, time) {
        if (!keyframes || keyframes.length === 0) return null

        // 找到关键帧并插值（类似KeyframeAnimation的实现）
        // ...插值逻辑
        return keyframes[0].value // 简化版本
    }
}

/**
 * 形变动画
 */
class MorphAnimation {
    constructor(name, targets, weights) {
        this.name = name
        this.targets = targets // 形变目标
        this.weights = weights // 权重轨道
        this.duration = this.calculateDuration()
    }

    /**
     * 计算动画时长
     */
    calculateDuration() {
        let maxDuration = 0
        this.weights.forEach(weightTrack => {
            if (weightTrack.keyframes.length > 0) {
                const lastKeyframe = weightTrack.keyframes[weightTrack.keyframes.length - 1]
                maxDuration = Math.max(maxDuration, lastKeyframe.time)
            }
        })
        return maxDuration
    }

    /**
     * 应用形变动画
     */
    apply(time, weight = 1.0) {
        this.weights.forEach((weightTrack, index) => {
            const morphWeight = this.interpolateWeight(weightTrack, time)
            if (morphWeight !== null && this.targets[index]) {
                // 应用形变权重
                this.targets[index].weight = morphWeight * weight
            }
        })
    }

    /**
     * 插值权重
     */
    interpolateWeight(weightTrack, time) {
        // 权重插值逻辑
        return 0 // 简化版本
    }
}

/**
 * 后处理效果系统
 */
export class PostProcessingSystem {
    constructor(gl, width, height) {
        this.gl = gl
        this.width = width
        this.height = height

        this.effects = []
        this.framebuffers = []
        this.textures = []

        this.initializeFramebuffers()
        this.initializeEffects()
    }

    /**
     * 初始化帧缓冲区
     */
    initializeFramebuffers() {
        const gl = this.gl

        // 创建两个帧缓冲区用于ping-pong渲染
        for (let i = 0; i < 2; i++) {
            const framebuffer = gl.createFramebuffer()
            const colorTexture = gl.createTexture()
            const depthBuffer = gl.createRenderbuffer()

            // 颜色纹理
            gl.bindTexture(gl.TEXTURE_2D, colorTexture)
            gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null)
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)

            // 深度缓冲区
            gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer)
            gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.width, this.height)

            // 绑定到帧缓冲区
            gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer)
            gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorTexture, 0)
            gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthBuffer)

            if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE) {
                console.error('后处理帧缓冲区创建失败')
            }

            this.framebuffers.push(framebuffer)
            this.textures.push(colorTexture)
        }

        gl.bindFramebuffer(gl.FRAMEBUFFER, null)
    }

    /**
     * 初始化后处理效果
     */
    initializeEffects() {
        this.effects = [
            new BloomEffect(this.gl),
            new FXAAEffect(this.gl),
            new ToneMappingEffect(this.gl),
            new VignetteEffect(this.gl),
            new ColorGradingEffect(this.gl)
        ]
    }

    /**
     * 添加效果
     */
    addEffect(effect) {
        this.effects.push(effect)
    }

    /**
     * 移除效果
     */
    removeEffect(effectClass) {
        this.effects = this.effects.filter(effect => !(effect instanceof effectClass))
    }

    /**
     * 渲染后处理效果
     */
    render(inputTexture) {
        const gl = this.gl
        let currentInput = inputTexture
        let currentFramebuffer = 0

        // 创建全屏四边形（如果还没有）
        if (!this.fullscreenQuad) {
            this.fullscreenQuad = this.createFullscreenQuad()
        }

        // 应用每个效果
        this.effects.forEach((effect, index) => {
            if (!effect.enabled) return

            const outputFramebuffer = this.framebuffers[currentFramebuffer]
            const outputTexture = this.textures[currentFramebuffer]

            // 最后一个效果直接渲染到屏幕
            const isLastEffect = index === this.effects.length - 1

            if (isLastEffect) {
                gl.bindFramebuffer(gl.FRAMEBUFFER, null)
            } else {
                gl.bindFramebuffer(gl.FRAMEBUFFER, outputFramebuffer)
            }

            gl.viewport(0, 0, this.width, this.height)
            gl.clear(gl.COLOR_BUFFER_BIT)

            // 应用效果
            effect.render(currentInput, this.fullscreenQuad)

            // 切换输入和输出
            if (!isLastEffect) {
                currentInput = outputTexture
                currentFramebuffer = 1 - currentFramebuffer
            }
        })
    }

    /**
     * 创建全屏四边形
     */
    createFullscreenQuad() {
        const gl = this.gl

        const vertices = new Float32Array([
            -1, -1, 0, 0,
            1, -1, 1, 0,
            -1, 1, 0, 1,
            1, 1, 1, 1
        ])

        const buffer = gl.createBuffer()
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer)
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)

        return { buffer, vertexCount: 4 }
    }

    /**
     * 调整大小
     */
    resize(width, height) {
        this.width = width
        this.height = height

        const gl = this.gl

        // 重新创建纹理和渲染缓冲区
        this.textures.forEach((texture, index) => {
            gl.bindTexture(gl.TEXTURE_2D, texture)
            gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null)
        })

        // 通知效果调整大小
        this.effects.forEach(effect => {
            if (effect.resize) {
                effect.resize(width, height)
            }
        })
    }

    /**
     * 清理资源
     */
    dispose() {
        const gl = this.gl

        // 清理帧缓冲区和纹理
        this.framebuffers.forEach(fb => gl.deleteFramebuffer(fb))
        this.textures.forEach(tex => gl.deleteTexture(tex))

        // 清理效果
        this.effects.forEach(effect => effect.dispose && effect.dispose())

        // 清理全屏四边形
        if (this.fullscreenQuad) {
            gl.deleteBuffer(this.fullscreenQuad.buffer)
        }
    }
}

/**
 * 基础后处理效果类
 */
class PostEffect {
    constructor(gl, fragmentShaderSource) {
        this.gl = gl
        this.enabled = true
        this.program = this.createProgram(fragmentShaderSource)
        this.uniforms = {}
    }

    /**
     * 创建着色器程序
     */
    createProgram(fragmentShaderSource) {
        const gl = this.gl

        const vertexShaderSource = `
            attribute vec2 a_position;
            attribute vec2 a_texCoord;
            varying vec2 v_texCoord;

            void main() {
                gl_Position = vec4(a_position, 0.0, 1.0);
                v_texCoord = a_texCoord;
            }
        `

        const vertexShader = this.createShader(gl.VERTEX_SHADER, vertexShaderSource)
        const fragmentShader = this.createShader(gl.FRAGMENT_SHADER, fragmentShaderSource)

        const program = gl.createProgram()
        gl.attachShader(program, vertexShader)
        gl.attachShader(program, fragmentShader)
        gl.linkProgram(program)

        if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
            console.error('后处理着色器程序链接失败:', gl.getProgramInfoLog(program))
            return null
        }

        return program
    }

    /**
     * 创建着色器
     */
    createShader(type, source) {
        const gl = this.gl
        const shader = gl.createShader(type)
        gl.shaderSource(shader, source)
        gl.compileShader(shader)

        if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
            console.error('着色器编译失败:', gl.getShaderInfoLog(shader))
            gl.deleteShader(shader)
            return null
        }

        return shader
    }

    /**
     * 渲染效果
     */
    render(inputTexture, quad) {
        const gl = this.gl

        gl.useProgram(this.program)

        // 绑定输入纹理
        gl.activeTexture(gl.TEXTURE0)
        gl.bindTexture(gl.TEXTURE_2D, inputTexture)
        gl.uniform1i(gl.getUniformLocation(this.program, 'u_texture'), 0)

        // 设置其他uniform
        this.setUniforms()

        // 绘制全屏四边形
        this.drawQuad(quad)
    }

    /**
     * 设置uniform变量
     */
    setUniforms() {
        // 子类实现
    }

    /**
     * 绘制四边形
     */
    drawQuad(quad) {
        const gl = this.gl

        gl.bindBuffer(gl.ARRAY_BUFFER, quad.buffer)

        const positionLocation = gl.getAttribLocation(this.program, 'a_position')
        const texCoordLocation = gl.getAttribLocation(this.program, 'a_texCoord')

        gl.enableVertexAttribArray(positionLocation)
        gl.enableVertexAttribArray(texCoordLocation)

        gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 16, 0)
        gl.vertexAttribPointer(texCoordLocation, 2, gl.FLOAT, false, 16, 8)

        gl.drawArrays(gl.TRIANGLE_STRIP, 0, quad.vertexCount)
    }

    /**
     * 清理资源
     */
    dispose() {
        if (this.program) {
            this.gl.deleteProgram(this.program)
        }
    }
}

/**
 * Bloom效果
 */
class BloomEffect extends PostEffect {
    constructor(gl) {
        const fragmentShader = `
            precision mediump float;
            uniform sampler2D u_texture;
            uniform float u_threshold;
            uniform float u_intensity;
            varying vec2 v_texCoord;

            void main() {
                vec4 color = texture2D(u_texture, v_texCoord);
                
                // 提取亮部
                float brightness = dot(color.rgb, vec3(0.299, 0.587, 0.114));
                if (brightness > u_threshold) {
                    gl_FragColor = vec4(color.rgb * u_intensity, color.a);
                } else {
                    gl_FragColor = vec4(0.0, 0.0, 0.0, color.a);
                }
            }
        `

        super(gl, fragmentShader)

        this.threshold = 0.8
        this.intensity = 1.5
    }

    setUniforms() {
        const gl = this.gl
        gl.uniform1f(gl.getUniformLocation(this.program, 'u_threshold'), this.threshold)
        gl.uniform1f(gl.getUniformLocation(this.program, 'u_intensity'), this.intensity)
    }
}

/**
 * FXAA抗锯齿效果
 */
class FXAAEffect extends PostEffect {
    constructor(gl) {
        const fragmentShader = `
            precision mediump float;
            uniform sampler2D u_texture;
            uniform vec2 u_resolution;
            varying vec2 v_texCoord;

            void main() {
                vec2 texelSize = 1.0 / u_resolution;
                
                // 简化版FXAA
                vec4 color = texture2D(u_texture, v_texCoord);
                vec4 colorN = texture2D(u_texture, v_texCoord + vec2(0.0, -texelSize.y));
                vec4 colorS = texture2D(u_texture, v_texCoord + vec2(0.0, texelSize.y));
                vec4 colorE = texture2D(u_texture, v_texCoord + vec2(texelSize.x, 0.0));
                vec4 colorW = texture2D(u_texture, v_texCoord + vec2(-texelSize.x, 0.0));
                
                vec4 avgColor = (color + colorN + colorS + colorE + colorW) / 5.0;
                gl_FragColor = mix(color, avgColor, 0.5);
            }
        `

        super(gl, fragmentShader)
    }

    setUniforms() {
        const gl = this.gl
        gl.uniform2f(gl.getUniformLocation(this.program, 'u_resolution'),
            this.gl.canvas.width, this.gl.canvas.height)
    }
}

/**
 * 色调映射效果
 */
class ToneMappingEffect extends PostEffect {
    constructor(gl) {
        const fragmentShader = `
            precision mediump float;
            uniform sampler2D u_texture;
            uniform float u_exposure;
            varying vec2 v_texCoord;

            vec3 toneMapping(vec3 color, float exposure) {
                color *= exposure;
                // Reinhard tone mapping
                return color / (1.0 + color);
            }

            void main() {
                vec4 color = texture2D(u_texture, v_texCoord);
                vec3 mapped = toneMapping(color.rgb, u_exposure);
                
                // Gamma correction
                mapped = pow(mapped, vec3(1.0 / 2.2));
                
                gl_FragColor = vec4(mapped, color.a);
            }
        `

        super(gl, fragmentShader)
        this.exposure = 1.0
    }

    setUniforms() {
        const gl = this.gl
        gl.uniform1f(gl.getUniformLocation(this.program, 'u_exposure'), this.exposure)
    }
}

/**
 * 晕影效果
 */
class VignetteEffect extends PostEffect {
    constructor(gl) {
        const fragmentShader = `
            precision mediump float;
            uniform sampler2D u_texture;
            uniform float u_intensity;
            uniform float u_extent;
            varying vec2 v_texCoord;

            void main() {
                vec4 color = texture2D(u_texture, v_texCoord);
                
                vec2 uv = v_texCoord - 0.5;
                float dist = length(uv);
                float vignette = smoothstep(u_extent, u_extent - u_intensity, dist);
                
                gl_FragColor = vec4(color.rgb * vignette, color.a);
            }
        `

        super(gl, fragmentShader)
        this.intensity = 0.3
        this.extent = 0.8
    }

    setUniforms() {
        const gl = this.gl
        gl.uniform1f(gl.getUniformLocation(this.program, 'u_intensity'), this.intensity)
        gl.uniform1f(gl.getUniformLocation(this.program, 'u_extent'), this.extent)
    }
}

/**
 * 颜色分级效果
 */
class ColorGradingEffect extends PostEffect {
    constructor(gl) {
        const fragmentShader = `
            precision mediump float;
            uniform sampler2D u_texture;
            uniform float u_brightness;
            uniform float u_contrast;
            uniform float u_saturation;
            uniform vec3 u_colorBalance;
            varying vec2 v_texCoord;

            vec3 rgb2hsv(vec3 c) {
                vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
                vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
                vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
                
                float d = q.x - min(q.w, q.y);
                float e = 1.0e-10;
                return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
            }

            vec3 hsv2rgb(vec3 c) {
                vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
                vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
                return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
            }

            void main() {
                vec4 color = texture2D(u_texture, v_texCoord);
                
                // 亮度调整
                color.rgb += u_brightness;
                
                // 对比度调整
                color.rgb = (color.rgb - 0.5) * u_contrast + 0.5;
                
                // 饱和度调整
                vec3 hsv = rgb2hsv(color.rgb);
                hsv.y *= u_saturation;
                color.rgb = hsv2rgb(hsv);
                
                // 色彩平衡
                color.rgb *= u_colorBalance;
                
                gl_FragColor = vec4(clamp(color.rgb, 0.0, 1.0), color.a);
            }
        `

        super(gl, fragmentShader)
        this.brightness = 0.0
        this.contrast = 1.0
        this.saturation = 1.0
        this.colorBalance = [1.0, 1.0, 1.0]
    }

    setUniforms() {
        const gl = this.gl
        gl.uniform1f(gl.getUniformLocation(this.program, 'u_brightness'), this.brightness)
        gl.uniform1f(gl.getUniformLocation(this.program, 'u_contrast'), this.contrast)
        gl.uniform1f(gl.getUniformLocation(this.program, 'u_saturation'), this.saturation)
        gl.uniform3fv(gl.getUniformLocation(this.program, 'u_colorBalance'), this.colorBalance)
    }
}

/**
 * 动画预设
 */
export const AnimationPresets = {
    // 旋转动画
    rotation: (target, duration = 2.0) => ({
        duration,
        tracks: [{
            property: 'rotation',
            keyframes: [
                { time: 0, value: [0, 0, 0] },
                { time: duration, value: [0, Math.PI * 2, 0] }
            ]
        }],
        target
    }),

    // 缩放动画
    scale: (target, fromScale = [0, 0, 0], toScale = [1, 1, 1], duration = 1.0) => ({
        duration,
        tracks: [{
            property: 'scale',
            keyframes: [
                { time: 0, value: fromScale },
                { time: duration, value: toScale }
            ]
        }],
        target
    }),

    // 浮动动画
    float: (target, amplitude = 0.5, duration = 2.0) => ({
        duration,
        tracks: [{
            property: 'position',
            keyframes: [
                { time: 0, value: [0, 0, 0] },
                { time: duration / 2, value: [0, amplitude, 0] },
                { time: duration, value: [0, 0, 0] }
            ]
        }],
        target
    })
}